class myPromise {
  constructor(func) {
    this.PromiseState = myPromise.PENDING;
    this.PromiseResult = null;
    this.onFullfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    try {
      func(this.resolve.bind(this), this.reject.bind(this));
    } catch (err) {
      this.reject(err)
    }
  }
  static PENDING = 'pending';
  static FULFILLED = 'fulfilled';
  static REJECTED = 'rejected';
  resolve (result) {
    if (this.PromiseState === myPromise.PENDING) {
      setTimeout(() => {
        this.PromiseState = myPromise.FULFILLED
        this.PromiseResult = result;
        this.onFullfilledCallbacks.forEach(callback => {
          callback(result)
        })
      });
    }
  }
  reject (reason) {
    if (this.PromiseState === myPromise.PENDING) {
      setTimeout(() => {
        this.PromiseState = myPromise.REJECTED;
        this.PromiseResult = reason;
        this.onRejectedCallbacks.forEach(callback => {
          callback(reason)
        })
      });
    }
  }
  then (onFullfilled, onRejected) {
    onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
    if (this.PromiseState === myPromise.PENDING) {
      this.onFullfilledCallbacks.push(onFullfilled);
      this.onRejectedCallbacks.push(onRejected)
    }
    if (this.PromiseState === myPromise.FULFILLED) {
      setTimeout(() => {
        onFullfilled(this.PromiseResult)
      })
    }
    if (this.PromiseState === myPromise.REJECTED) {
      setTimeout(() => {
        onRejected(this.PromiseResult)
      })
    }
  }
}

module.exports = myPromise;